<template>
	<span ref="kbElement" :class="['ui-kb-input', active && 'is-active', showStatus && `is-${status}`]">
		<slot :kbCode="strFormart">
			{{strFormart}}
		</slot>
	</span>
</template>

<script setup>
	
	import { ref, computed } from 'vue';
	import useWithin from '@/compositions/useWithin';

	const props = defineProps({
		modelValue: String,
		placeholder: '',
		showStatus: {
			type: Boolean,
			default: true
		}
	})
	
	const emits = defineEmits(['update:modelValue', 'change', 'notallowed']);
	
	const kbElement = ref();
	
	const strFormart = computed(() => {
		return props.modelValue || props.placeholder;
	})
	
	useWithin(kbElement, {
		onWithin: openKb,
		onWithout: closeKb
	});

	const active = ref(false);
	const status = ref('');
	
	function openKb() {
		active.value = true;
		status.value = 'waiting';
		document.addEventListener('keydown', downKb);
		document.addEventListener('keypress', pressKb);
	}
	
	function downKb(e) {
		const kbKey = e.key;
		if (kbKey === 'Backspace') {
			status.value = 'waiting';
			emits('update:modelValue', null);
			emits('change', null);
		}
	}
	
	function pressKb(e) {
		const kbCode = e.code;
		if (/Digit\d/.test(kbCode) || /Numpad\d/.test(kbCode) || /Key[A-Z]/.test(kbCode)) {
			status.value = 'success';
			emits('update:modelValue', kbCode);
			emits('change', kbCode);
		} else {
			status.value = 'warning';
			emits('notallowed', kbCode);
		}
	}
	
	function closeKb() {
		active.value = false;
		status.value = '';
		document.removeEventListener('keydown', downKb);
		document.removeEventListener('keypress', pressKb);
	}
	
</script>

<style lang="scss" scoped>
	
	@import '@/theme/material/animate';
	
	.ui-kb-input {
		display: inline-block;
		padding: 4px;
		text-align: center;
		cursor: pointer;
		outline: none;
		transition: .25s ease-in;
		box-sizing: border-box;
		border-radius: inherit;
		&.is-active {
			cursor: text;
		}
		&.is-waiting {
			outline: 1px solid #409eff;
			box-shadow: 0 0 4px #409eff;
		}
		&.is-success {
			outline: 1px solid #67c23a;
			box-shadow: 0 0 4px #67c23a;
		}
		&.is-warning {
			@include animateAttr($duration: 500ms, $count: 1);
			@include animateShake;
			outline: 1px solid #e6a23c;
			box-shadow: 0 0 4px #e6a23c;
		}
	}
	
</style>
